﻿#include "NRJB/NRJB103Constructer.h"
#include "utils.h"

// 参数源设备地址为 本机ip地址的最后一个字段
NRJB103Constructer::NRJB103Constructer()
{
    m_cpuAddr = 0xff;

    // 在构造心跳报文的时候直接给初始化为目标设备的ip地址的最后一个字段

}

NRJB103Constructer::~NRJB103Constructer()
{

}

QByteArray NRJB103Constructer::constructHeartPacket(ushort srcDevAddr, ushort destDevAddr)
{
    // APCI 心跳 90eb 14000000 90eb 0000 dc00 0000ffff4b002b00500000000000ffff
    NRJB_APCI_Frame apci;
//    apci.head1 = 0x90EB;
//    apci.len = 0x14000000;      // 心跳报文无ASDU，长度固定为20
//    apci.head2 = 0x90EB;
    apci.srcFactorAddr = ADDR_SRC_FACTORY;
    apci.srcDeviceAddr = (Utils::unsignedToHexStr( srcDevAddr));    // ip地址最后一个字段220
    apci.destFactoryAddr = ADDR_DEST_FACTORY;
    apci.destDeviceAddr = Utils::unsignedToHexStr( destDevAddr);   //
    apci.dataNo = "0100";           // 数据编号第1个
    apci.deviceType = "2b00";       // 南瑞继保建场站时候组态设定的设备类型编号
    apci.deviceNetState = "5000";    // 目前看都是0x5000;
    apci.firstRuteDeviceAddr = "0000";
    apci.lastRuteDeviceAddr = "0000";
    apci.reseverByte = "ffff";  // 保留字
    return apci.getAPCI(srcDevAddr,destDevAddr);
}

QByteArray NRJB103Constructer::constructReadGroupInfo(ushort srcDevAddr, ushort destDevAddr,const QString &groupNo,const QString &KOD)
{
    QByteArray heartMsg = constructHeartPacket(srcDevAddr, destDevAddr);

    heartMsg[4] = '1';
    heartMsg[5] = 'f';

    //   apci + 15 81 2a ff fe f0 00 00 00 00 0a
    //  rii ngd gr gin kod
    //90eb1f00000090eb000023000000dc0002002b00500000000000ffff 15 81 2a ff fe f1 00 00 05 00 0a
    //90eb1400000090eb000001080000022001002b00500000000000ffff15812afffef100000500OA
    QByteArray cmd = heartMsg.append("15812afffef10000");

    QString cpuAddr = QString::number(destDevAddr, 16); //获取界面配置项， 也等于 dest addr

    cmd.append(Utils::intToHexStr(groupNo.toUInt(nullptr, 10),2));
    cmd.append("00");   // ngd = 0；
    cmd.append(KOD);

    return cmd;
}

//90eb1f00000090eb0000dc000000ffff06002b00500000000000ffff 15812afffef0000000000a
QByteArray NRJB103Constructer::constructReadAllTitles(ushort srcDevAddr, ushort destDevAddr)
{
    QByteArray  readAllTitlesCMD;

    // apci 头部报文构造
    QByteArray apciByteArray =  constructHeartPacket(srcDevAddr, destDevAddr);

    //将心跳 apci的报文长度 由20改为 1f , 加了 asdu 长度为 11个字节
    apciByteArray[4] = '1';
    apciByteArray[5] = 'f';

    QString cpuAddr = QString::number(destDevAddr, 16); //获取界面配置项， 也等于 dest addr

    // ASDU 15 81 2A 01 F1 00 01 00 0A
    ASDUStruct  readTitlesAsdu = m_asduConstructer->constructReadAllTitles(cpuAddr);
    readAllTitlesCMD.push_back(apciByteArray);
    readAllTitlesCMD.push_back(readTitlesAsdu.asduToQString().toLatin1());

    return readAllTitlesCMD;
}

// 标题 90eb1f00000090eb00006c000000dc0001002b00500000000000ffff 15 81 2a ff fe f0 00 00 00 00 0A
//     90eb2200000090eb00006c000000dc0000a00b00500000000000ffff 15 81 2A dc FE F0 77 01 00 00 00 00 00 00
QByteArray NRJB103Constructer::constructReadAllTitles(QString srcDevAddr, QString destDevAddr)
{
    QByteArray  readAllTitlesCMD;

    ushort srcAddr = Utils::uintStrToHexStr(destDevAddr.split('.')[3],4).toUInt(nullptr,16);
    ushort destAddr = Utils::uintStrToHexStr(srcDevAddr.split('.')[3],4).toUInt(nullptr,16);

    // apci 头部报文构造
    QByteArray apciByteArray =  constructHeartPacket(srcAddr, destAddr);

    //将心跳 apci的报文长度 由20改为 1f , 加了 asdu 长度为 11个字节
    apciByteArray[4] = '1';
    apciByteArray[5] = 'f';

    QString cpuAddr1 = QString::number(destAddr, 16).mid(0,2); //获取界面配置项， 也等于 dest addr

    // ASDU 15 81 2A 01 F1 00 01 00 0A
    ASDUStruct  readTitlesAsdu = m_asduConstructer->constructReadAllTitles(cpuAddr1);
    readAllTitlesCMD.push_back(apciByteArray);
    readAllTitlesCMD.push_back(readTitlesAsdu.asduToQString().toLatin1());

    return readAllTitlesCMD;
}


uint8_t NRJB103Constructer::SumCheck(const char *packet, int32_t length)
{
    uint8_t result = 0;
    for ( int32_t i = 0; i < length; i++ )
    {
        result += packet[i];
    }

    return result;
}

uint8_t NRJB103Constructer::SumCheck(const QString &packet, int32_t length)
{
    QByteArray packetByteArray = packet.toLatin1();
    const char* pack = packetByteArray;
    uint8_t result = 0;
    for( int32_t i = 0; i < length; i++ )
    {
        result += pack[i];
    }

    return result;
}

uint8_t NRJB103Constructer::SumCheck(const QByteArray &packet, int32_t length)
{
    const char* pack = packet;
    uint8_t result = 0;
    for ( int32_t i = 0; i < length; i++ )
    {
        result += pack[i];
    }

    return result;
}

QByteArray NRJB103Constructer::apciToByteArray(NRJB_APCI_Frame apci)
{
    QByteArray ret;
    ret.push_back(apci.head1);
    ret.push_back(apci.len);
    ret.push_back(apci.head2);
    ret.push_back(apci.srcFactorAddr);
    ret.push_back(apci.srcDeviceAddr);
    ret.push_back(apci.destFactoryAddr);
    ret.push_back(apci.destDeviceAddr);
    ret.push_back(apci.dataNo);
    ret.push_back(apci.deviceType);
    ret.push_back(apci.deviceNetState);
    ret.push_back(apci.firstRuteDeviceAddr);
    ret.push_back(apci.lastRuteDeviceAddr);
    ret.push_back(apci.reseverByte);
    return ret;
}
